package com.bms.admin.base.index.web;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.bms.admin.base.index.form.LoginForm;
import com.bms.admin.base.index.model.NowUser;
import com.bms.admin.base.log.entity.LoginLog;
import com.bms.admin.base.log.service.ILoginLogService;
import com.bms.admin.base.user.entity.User;
import com.bms.admin.base.user.service.IUserService;
import com.bms.admin.config.annotation.LoginUser;
import com.bms.admin.util.RedisUtil;
import com.bms.auth.SubjectUtil;
import com.bms.common.base.common.bean.Result;
import com.bms.common.base.common.exception.EnumSvrResult;
import com.bms.common.base.common.util.IPUtils;
import com.bms.common.base.common.util.MD5Util;
import com.bms.common.base.web.BaseController;
import com.feilong.core.Validator;
import com.feilong.core.bean.ConvertUtil;
import com.feilong.core.bean.PropertyUtil;
import com.feilong.core.date.DateUtil;
import com.google.code.kaptcha.Producer;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import springfox.documentation.annotations.ApiIgnore;

@RestController
@Api(value="Login-Api",tags="登录接口")
public class LoginController extends BaseController{

	@Autowired
	private IUserService userService;

	@Autowired
	private ILoginLogService loginLogService;

	@Autowired
	private Producer producer;

	@Autowired
	private RedisUtil redisUtil;
	
    /**
     * 获取验证码
     * @param response
     * @param uuid
     * @throws ServletException
     * @throws IOException
     */
    @GetMapping("captcha.jpg")
    @ApiOperation("获取验证码")
    public void captcha(HttpServletResponse response,@RequestParam String uuid)throws Exception {
        response.setHeader("Cache-Control", "no-store, no-cache");
        response.setContentType("image/jpeg");
        String code = producer.createText();
        redisUtil.setEx("captcha:"+uuid, code,5,TimeUnit.MINUTES);
		BufferedImage image = producer.createImage(code);
		ServletOutputStream out = response.getOutputStream();
		ImageIO.write(image, "jpg", out);
		IOUtils.closeQuietly(out);
    }

	@ApiOperation("登录")
	@PostMapping("login")
	public Result login(HttpServletRequest request,@Validated @RequestBody LoginForm form) {
		String captcha =redisUtil.get("captcha:"+form.getUuid());
		if(Validator.isNullOrEmpty(captcha) || !captcha.equalsIgnoreCase(form.getCaptcha())) {
			return fail(EnumSvrResult.ERROR_MSG_CODE);
		}
	    List<User> loginUsers = userService.selectByMap(ConvertUtil.toMap("username", form.getUsername()));
	    Map<String,Object> result = new HashMap<>();
	    if(Validator.isNullOrEmpty(loginUsers)){
	        return fail(EnumSvrResult.DEFIN_ACCOUNT);
	    }
	    User loginUser =loginUsers.get(0);
	    if(loginUser.getStatus()!=1){
	        return fail(EnumSvrResult.LOCKED_ACCOUNT);
	    }else if(!MD5Util.inputPassToDbPass(form.getPassword(), loginUser.getSalt()).equals(loginUser.getPassword())){
	        return fail(EnumSvrResult.ERROR_PASSWORD);
	    }
	    Set<String> permissions = userService.getUserPermissions(loginUser.getId());
	    String token = SubjectUtil.getInstance().createToken(PropertyUtil.describe(loginUser,"id","username","companyId"), DateUtil.addDay(new Date(), 30));  //第二个参数是到期时间
	    saveLoginLog(request, "登录", loginUser.getUsername());
	    result.put("token", token);
	    result.put("user", loginUser);
	    result.put("access", permissions);
	    return json(result);
	}

	@ApiOperation("注销")
	@GetMapping("logout")
	public Result logout(HttpServletRequest request,@ApiIgnore @LoginUser NowUser nowUser,@ApiIgnore @RequestHeader String token) {
		SubjectUtil.getInstance().expireToken(nowUser.getUserId().toString(), token);
		saveLoginLog(request, "注销", nowUser.getUsername());
	    return success();
	}
	
	private void saveLoginLog(HttpServletRequest request,String msg,String username){
		LoginLog log = new LoginLog();
		log.setCreateTime(new Date());
		log.setIp(IPUtils.getIpAddr(request));
		log.setMessage(msg);
		log.setUsername(username);
		loginLogService.insert(log);
	}
}
